package site.sorghum.ddl;

import site.sorghum.ddl.entity.DdlColumnWrap;
import site.sorghum.ddl.entity.DdlIndexWrap;
import site.sorghum.ddl.entity.DdlTableWrap;
import site.sorghum.ddl.enums.DbType;
import site.sorghum.ddl.field.TypeConverter;

import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 数据库DDL方言接口
 */
public interface DDLDialect {

    /**
     * 生成添加列的DDL语句
     *
     * @param column 列定义
     * @return 完整的ALTER TABLE ADD COLUMN语句
     */
    String generateAddColumnDDL(DdlColumnWrap column);

    /**
     * 获取数据库类型
     *
     * @return 数据库类型
     */
    DbType getDatabaseType();

    /**
     * 生成建表的DDL语句
     *
     * @param table 表定义
     * @return 完整的CREATE TABLE语句
     */
    List<String> generateCreateTableDDL(DdlTableWrap table);


    /**
     * 生成索引的DDL语句
     *
     * @param indexName   索引名称
     * @param columnWraps 列定义
     * @param unique      是否唯一索引
     * @return 完整的CREATE INDEX语句
     */
    String generateAddIndexDDL(String indexName, List<DdlColumnWrap> columnWraps, boolean unique);

    /**
     * 生成索引的DDL语句
     *
     * @param columnWraps 列定义
     * @param unique      是否唯一索引
     * @return 完整的CREATE INDEX语句
     */
    default String generateAddIndexDDL(List<DdlColumnWrap> columnWraps, boolean unique) {
        return generateAddIndexDDL(null, columnWraps, unique);
    }

    /**
     * 生成删除列的DDL语句
     * @param table 表名
     * @param column 列名
     * @return SQL语句
     */
    String generateDropColumnDDL(String table,String column);

    /**
     * 生成删除索引的DDL语句
     * @param table 表名
     * @param indexName 索引名
     * @return SQL语句
     */
    String generateDropIndexDDL(String table,String indexName);


    /**
     * 生成索引的DDL语句
     *
     * @param ddlIndexWrap 索引定义
     * @return 定义
     */
    default String generateAddIndexDDL(DdlIndexWrap ddlIndexWrap) {
        {
            if (ddlIndexWrap == null) {
                return "";
            }
            return generateAddIndexDDL(
                    ddlIndexWrap.getIndexName(),
                    ddlIndexWrap.getColumnNames().stream().map(it -> DdlColumnWrap.simpleBuild(ddlIndexWrap.getTable(), it)).collect(Collectors.toList()),
                    ddlIndexWrap.isUnique()
            );
        }
    }

    /**
     * 从数据源中获取表和列定义
     *
     * @return 表定义
     */
    DdlTableWrap fromDataSource(
            String schema,
            String tableName,
            Function<String, List<String>> pks,
            Function<String, DdlTableWrap> table,
            Function<String, List<DdlColumnWrap>> columns,
            Function<String, List<DdlIndexWrap>> indexes);

    /**
     * 获取所有表名
     *
     * @param schema 数据库模式
     * @param tables 表名查询函数
     * @return 表名集合
     */
    List<String> fetchAllTableNames(String schema, Function<String, List<String>> tables);

    /**
     * 获取类型转换器
     *
     * @return 类型转换器
     */
    TypeConverter typeConverter();
}